use pumpkin_macros::packet;
use pumpkin_util::math::{vector2::Vector2, vector3::Vector3};

use crate::{
    codec::{bitset::Bitset, var_uint::VarUInt, var_ulong::VarULong},
    serial::PacketRead,
};

#[derive(Debug, PacketRead)]
#[packet(144)]
pub struct SPlayerAuthInput {
    // https://mojang.github.io/bedrock-protocol-docs/html/PlayerAuthInputPacket.html
    pub pitch: f32,
    pub yaw: f32,
    pub position: Vector3<f32>,
    pub move_vec: Vector2<f32>,
    pub head_rotation: f32,
    pub input_data: Bitset<65>,
    pub input_mode: VarUInt,
    pub play_mode: VarUInt,
    pub new_interaction_model: VarUInt,
    pub interact_rotation: Vector2<f32>,
    pub client_tick: VarULong,
    pub pos_delta: Vector3<f32>,
    pub analog_move: Vector2<f32>,
    pub camera_orientation: Vector3<f32>,
    pub raw_move_vec: Vector2<f32>,
}

#[derive(Clone, Copy)]
pub enum InputData {
    // https://mojang.github.io/bedrock-protocol-docs/html/enums.html#PlayerAuthInputPacket::InputData
    Ascend = 0,
    Descend = 1,
    JumpDown = 3,
    SprintDown = 4,
    ChangeHeight = 5,
    Jumping = 6,
    AutoJumpingInWater = 7,
    Sneaking = 8,
    SneakDown = 9,
    Up = 10,
    Down = 11,
    Left = 12,
    Right = 13,
    UpLeft = 14,
    UpRight = 15,
    WantUp = 16,
    WantDown = 17,
    WantDownSlow = 18,
    WantUpSlow = 19,
    Sprinting = 20,
    AscendBlock = 21,
    DescendBlock = 22,
    SneakToggleDown = 23,
    PersistSneak = 24,
    StartSprinting = 25,
    StopSprinting = 26,
    StartSneaking = 27,
    StopSneaking = 28,
    StartSwimming = 29,
    StopSwimming = 30,
    StartJumping = 31,
    StartGliding = 32,
    StopGliding = 33,
    PerformItemInteraction = 34,
    PerformBlockActions = 35,
    PerformItemStackRequest = 36,
    HandledTeleport = 37,
    Emoting = 38,
    MissedSwing = 39,
    StartCrawling = 40,
    StopCrawling = 41,
    StartFlying = 42,
    StopFlying = 43,
    ClientAckServerData = 44,
    IsInClientPredictedVehicle = 45,
    PaddlingLeft = 46,
    PaddlingRight = 47,
    BlockBreakingDelayEnabled = 48,
    HorizontalCollision = 49,
    VerticalCollision = 50,
    DownLeft = 51,
    DownRight = 52,
    StartUsingItem = 53,
    IsCameraRelativeMovementEnabled = 54,
    IsRotControlledByMoveDirection = 55,
    StartSpinAttack = 56,
    StopSpinAttack = 57,
    IsHotbarOnlyTouch = 58,
    JumpReleasedRaw = 59,
    JumpPressedRaw = 60,
    JumpCurrentRaw = 61,
    SneakReleasedRaw = 62,
    SneakPressedRaw = 63,
    SneakCurrentRaw = 64,
    InputNum = 65,
}

impl From<InputData> for usize {
    fn from(value: InputData) -> Self {
        value as Self
    }
}

pub enum InputMode {
    Undefined = 0,
    Mouse = 1,
    Touch = 2,
    GamePad = 3,
    MotionController = 4,
}
